#pragma once
#ifndef MYDIRECT3D7_H
#define MYDIRECT3D7_H

#include "common.h"
#include "MyDirect3DDevice7.h"
#include "MyDirect3DVertexBuffer7.h"

class MyDirect3D7 : public IDirect3D7 {
public:
    MyDirect3D7(IDirect3D7* direct3d7) : direct3d7(direct3d7) {
        DebugWrite("MyDirect3D7::MyDirect3D7\n");
    }

    /*** IUnknown methods ***/
    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
        DebugWrite("MyDirect3D7::QueryInterface\n");
        return this->direct3d7->QueryInterface(riid, ppvObj);
    }

    ULONG STDMETHODCALLTYPE AddRef() {
        DebugWrite("MyDirect3D7::AddRef\n");
        return this->direct3d7->AddRef();
    }

    ULONG STDMETHODCALLTYPE Release() {
        DebugWrite("MyDirect3D7::Release\n");
        ULONG count = this->direct3d7->Release();
        if (0 == count) {
            delete this;
        }

        return count;
    }

    /*** IDirect3D7 methods ***/
    HRESULT STDMETHODCALLTYPE CreateDevice (REFCLSID rclsid, LPDIRECTDRAWSURFACE7 lpDDS, LPDIRECT3DDEVICE7* lplpD3DDevice) {
        DebugWrite("MyDirect3D7::CreateDevice\n");
        HRESULT hr = this->direct3d7->CreateDevice(rclsid, lpDDS, lplpD3DDevice);

        if (SUCCEEDED(hr)) {
            *lplpD3DDevice = new MyDirect3DDevice7(this, *lplpD3DDevice);
        }

        return hr;
    }

    HRESULT STDMETHODCALLTYPE CreateVertexBuffer(LPD3DVERTEXBUFFERDESC lpVBDesc, LPDIRECT3DVERTEXBUFFER7* lplpD3DVertexBuffer, DWORD dwFlags) {
        DebugWrite("MyDirect3D7::CreateVertexBuffer\n");
        HRESULT hr = this->direct3d7->CreateVertexBuffer(lpVBDesc, lplpD3DVertexBuffer, dwFlags);

        if (SUCCEEDED(hr)) {
            *lplpD3DVertexBuffer = new MyDirect3DVertexBuffer7(*lplpD3DVertexBuffer);
        }

        return hr;
    }

    HRESULT STDMETHODCALLTYPE EnumDevices(LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, LPVOID lpUserArg) {
        DebugWrite("MyDirect3D7::EnumDevices\n");
        return this->direct3d7->EnumDevices(lpEnumDevicesCallback, lpUserArg);
    }

    HRESULT STDMETHODCALLTYPE EvictManagedTextures() {
        DebugWrite("MyDirect3D7::EvictManagedTextures\n");
        return this->direct3d7->EvictManagedTextures();
    }

    HRESULT STDMETHODCALLTYPE EnumZBufferFormats(REFCLSID riidDevice, LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, LPVOID lpContext) {
        DebugWrite("MyDirect3D7::EnumZBufferFormats\n");
        return this->direct3d7->EnumZBufferFormats(riidDevice, lpEnumCallback, lpContext);
    }

private:
    IDirect3D7* direct3d7;
};

#endif
